import 'dart:io';
import 'package:path/path.dart';

class Generator {
  Generator(
      {this.base,
      this.output,
      this.host,
      this.sitemap: 'sitemap.xml',
      List<String> disallow}) {
    base = normalize(base);
    output = output ?? base;
    if (null != disallow && disallow.isNotEmpty) {
      _disallow = disallow.map((String str) {
        return join(base, str);
      }).toList();
    }
  }

  String host;
  String base;
  String output;
  String sitemap;
  String content = '''
<?xml version="1.0" encoding="UTF-8"?>
<urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
''';
  RegExp checkHtml = new RegExp(r'\.html$', caseSensitive: false);

  List<String> _disallow;

  void generate() {
//    print(isAllow(_disallow.first));
//    return;
    Directory directory = new Directory(base);
    if (FileSystemEntity.isDirectorySync(directory.path)) {
      content += getSection(host, priority: 1.0);
      resolve(directory, depth: 1);
    } else {
      print('Is not directory: $base');
    }
    content += '''
</urlset>
''';
    String sitemapPath = absolute(join(normalize(output), sitemap));
    File file = new File(sitemapPath);
    file.writeAsStringSync(content);
    print('Generated successfly in $sitemapPath');
  }

  void resolve(FileSystemEntity file, {int depth = 0}) {
    if (!isAllow(file.path)) {
      print('Skip path: ${file.path}');
      return;
    }
    print('Resolve path: ${file.path}');
    List<FileSystemEntity> list = (file as Directory).listSync();
    list.forEach((FileSystemEntity entity) {
      if (FileSystemEntity.isDirectorySync(entity.path)) {
        resolve(entity, depth: depth + 1);
      } else {
        if (checkHtml.hasMatch(entity.path)) {
          String url = getUrl(entity.path);
          print('Record url: $url');
          String section = getSection(url, priority: 1.0 - 0.1 * depth);
          content += section;
        }
      }
    });
  }

  bool isAllow(String uri) {
    return null == _disallow ? true : !_disallow.contains(normalize(uri));
  }

  String getUrl(String path) {
    Uri uri = toUri(path.substring(base.length + 1, path.length));
    return host + '/' + uri.path;
  }

  String getSection(String url, {double priority: 0.5, String lastmod}) {
    return '''
<url>
  <loc>$url</loc>${null != lastmod
        ? '\n<lastmod>2018-05-14T07:40:20+00:00</lastmod>'
        : ''}
  <priority>$priority</priority>
</url>
''';
  }
}
